ESTI019 - CSM¶

Lab3 - Codificação de Imagem por DCT e Animação¶

In [3]:
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
In [4]:
bgr1 = cv.imread('./arquivos_notebook/messi.jpg') # leitura no formato BGR!
altura, largura, camadas = bgr1.shape
print("Resolução: ", largura, " x ", altura, "PIXELS. ", camadas, " camadas.")
Resolução:  548  x  342 PIXELS.  3  camadas.

Separa os canais e re-arranja para formar imagem RGB

In [5]:
b1, g1, r1 = cv.split(bgr1)
rgb2 = cv.merge([r1,g1,b1])

Q1 - O que foi feito aqui?¶

A primeira linha do código acima divide uma matriz multicanal em várias matrizes de canal único.

A segunda linha os une novamente na ordem correta, pos a função cv.imread armazena os canais na ordem BGR.

Imprime cores trocadas (BGR) e reais (RGB)

In [6]:
plt.figure(figsize=[12, 5])
plt.subplot(121); plt.imshow(bgr1); plt.title('BGR')
plt.subplot(122); plt.imshow(rgb2); plt.title('RGB')
Out[6]:
Text(0.5, 1.0, 'RGB')

Converte para os formatos YCrCb e HSV

In [7]:
ycrcb = cv.cvtColor(bgr1, cv.COLOR_BGR2YCrCb)
hsv = cv.cvtColor(bgr1, cv.COLOR_BGR2HSV)
plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(rgb2); plt.title('RGB')
plt.subplot(132); plt.imshow(ycrcb); plt.title('YCrCb')
plt.subplot(133); plt.imshow(hsv); plt.title('HSV')
Out[7]:
Text(0.5, 1.0, 'HSV')

Separação das Camadas RGB individualmente

In [8]:
imageR = rgb2.copy()
imageR[:, :, 1:3] = 0
imageG = rgb2.copy()
imageG[:, :, 0] = 0; imageG[:, :, 2] = 0
imageB = rgb2.copy()
imageB[:, :, 0:2] = 0     
# Q2 - O que foi feito aqui?
# Nesta etapa copia-se a imagem original e zera as outras camadas para sobrar apenas as camadas R, G e B em cada cópia
plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(imageR); plt.title('RGB_Camada R')
plt.subplot(132); plt.imshow(imageG); plt.title('RGB_Camada G')
plt.subplot(133); plt.imshow(imageB); plt.title('RGB_Camada B')
Out[8]:
Text(0.5, 1.0, 'RGB_Camada B')

Separação dos Canais YCbCr

In [9]:
y1, cr1, cb1 = cv.split(ycrcb)
imageCR = ycrcb.copy()
imageCR[:, :, 0] = 0
imageCR[:, :, 2] = 0
Cr = cv.cvtColor(imageCR, cv.COLOR_YCrCb2RGB)

imageCB = ycrcb.copy()
imageCB[:, :, 0] = 0
imageCB[:, :, 1] = 0
Cb = cv.cvtColor(imageCB, cv.COLOR_YCrCb2RGB)

plt.figure(figsize=[15, 5])
plt.subplot(141); plt.imshow(rgb2); plt.title('RGB original')
plt.subplot(142); plt.imshow(y1, cmap='gray'); plt.title('YCrCb_Y')
plt.subplot(143); plt.imshow(Cr); plt.title('YCrCb_Cr')
plt.subplot(144); plt.imshow(Cb); plt.title('YCrCb_Cb')
Out[9]:
Text(0.5, 1.0, 'YCrCb_Cb')

Com as Imagens do Grupo:¶

  1. Faça o mesmo com uma imagem de cada integrante do grupo e
  2. Com a foto montagem de todos os do grupo, lembrando das roupas com cores diferentes, preferencialmente (R, G e B).
In [10]:
adinan_bgr = cv.imread('./fotos_grupo/adinan_home.jpg') # leitura no formato BGR!
b1_a, g1_a, r1_a = cv.split(adinan_bgr)
rgb_adinan = cv.merge([r1_a,g1_a,b1_a])
plt.figure(figsize=[10, 2.5])
plt.subplot(121); plt.imshow(adinan_bgr); plt.title('BGR')
plt.subplot(122); plt.imshow(rgb_adinan); plt.title('RGB')

adinanR = rgb_adinan.copy()
adinanR[:, :, 1:3] = 0
adinanG = rgb_adinan.copy()
adinanG[:, :, 0] = 0; adinanG[:, :, 2] = 0
adinanB = rgb_adinan.copy()
adinanB[:, :, 0:2] = 0    
plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(adinanR); plt.title('RGB_Camada R')
plt.subplot(132); plt.imshow(adinanG); plt.title('RGB_Camada G')
plt.subplot(133); plt.imshow(adinanB); plt.title('RGB_Camada B')

adinan_ycrcb = cv.cvtColor(adinan_bgr, cv.COLOR_BGR2YCrCb)
adinan_hsv = cv.cvtColor(adinan_bgr, cv.COLOR_BGR2HSV)
plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(rgb_adinan); plt.title('RGB')
plt.subplot(132); plt.imshow(adinan_ycrcb); plt.title('YCrCb')
plt.subplot(133); plt.imshow(adinan_hsv); plt.title('HSV')
Out[10]:
Text(0.5, 1.0, 'HSV')
In [11]:
joao_bgr = cv.imread('./fotos_grupo/joao_home.jpg') # leitura no formato BGR!
b1_a, g1_a, r1_a = cv.split(joao_bgr)
rgb_joao = cv.merge([r1_a,g1_a,b1_a])
plt.figure(figsize=[10, 2.5])
plt.subplot(121); plt.imshow(joao_bgr); plt.title('BGR')
plt.subplot(122); plt.imshow(rgb_joao); plt.title('RGB')


joaoR = rgb_joao.copy()
joaoR[:, :, 1:3] = 0
joaoG = rgb_joao.copy()
joaoG[:, :, 0] = 0; joaoG[:, :, 2] = 0
joaoB = rgb_joao.copy()
joaoB[:, :, 0:2] = 0    
plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(joaoR); plt.title('RGB_Camada R')
plt.subplot(132); plt.imshow(joaoG); plt.title('RGB_Camada G')
plt.subplot(133); plt.imshow(joaoB); plt.title('RGB_Camada B')


joao_ycrcb = cv.cvtColor(joao_bgr, cv.COLOR_BGR2YCrCb)
joao_hsv = cv.cvtColor(joao_bgr, cv.COLOR_BGR2HSV)
plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(rgb_joao); plt.title('RGB')
plt.subplot(132); plt.imshow(joao_ycrcb); plt.title('YCrCb')
plt.subplot(133); plt.imshow(joao_hsv); plt.title('HSV')
Out[11]:
Text(0.5, 1.0, 'HSV')
In [12]:
marcelo_bgr = cv.imread('./fotos_grupo/marcelo_home.jpg') # leitura no formato BGR!
b1_a, g1_a, r1_a = cv.split(marcelo_bgr)
rgb_marcelo = cv.merge([r1_a,g1_a,b1_a])
plt.figure(figsize=[10, 2.5])
plt.subplot(121); plt.imshow(marcelo_bgr); plt.title('BGR')
plt.subplot(122); plt.imshow(rgb_marcelo); plt.title('RGB')


marceloR = rgb_marcelo.copy()
marceloR[:, :, 1:3] = 0
marceloG = rgb_marcelo.copy()
marceloG[:, :, 0] = 0; marceloG[:, :, 2] = 0
marceloB = rgb_marcelo.copy()
marceloB[:, :, 0:2] = 0    
plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(marceloR); plt.title('RGB_Camada R')
plt.subplot(132); plt.imshow(marceloG); plt.title('RGB_Camada G')
plt.subplot(133); plt.imshow(marceloB); plt.title('RGB_Camada B')

marcelo_ycrcb = cv.cvtColor(marcelo_bgr, cv.COLOR_BGR2YCrCb)
marcelo_hsv = cv.cvtColor(marcelo_bgr, cv.COLOR_BGR2HSV)
plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(rgb_marcelo); plt.title('RGB')
plt.subplot(132); plt.imshow(marcelo_ycrcb); plt.title('YCrCb')
plt.subplot(133); plt.imshow(marcelo_hsv); plt.title('HSV')
Out[12]:
Text(0.5, 1.0, 'HSV')
In [13]:
walter_bgr = cv.imread('./fotos_grupo/walter_home.jpg') # leitura no formato BGR!
b1_a, g1_a, r1_a = cv.split(walter_bgr)
rgb_walter = cv.merge([r1_a,g1_a,b1_a])
plt.figure(figsize=[10, 2.5])
plt.subplot(121); plt.imshow(walter_bgr); plt.title('BGR')
plt.subplot(122); plt.imshow(rgb_walter); plt.title('RGB')


walterR = rgb_walter.copy()
walterR[:, :, 1:3] = 0
walterG = rgb_walter.copy()
walterG[:, :, 0] = 0; walterG[:, :, 2] = 0
walterB = rgb_walter.copy()
walterB[:, :, 0:2] = 0    
plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(walterR); plt.title('RGB_Camada R')
plt.subplot(132); plt.imshow(walterG); plt.title('RGB_Camada G')
plt.subplot(133); plt.imshow(walterB); plt.title('RGB_Camada B')

walter_ycrcb = cv.cvtColor(walter_bgr, cv.COLOR_BGR2YCrCb)
walter_hsv = cv.cvtColor(walter_bgr, cv.COLOR_BGR2HSV)
plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(rgb_walter); plt.title('RGB')
plt.subplot(132); plt.imshow(walter_ycrcb); plt.title('YCrCb')
plt.subplot(133); plt.imshow(walter_hsv); plt.title('HSV')
Out[13]:
Text(0.5, 1.0, 'HSV')

COMPRESSÃO DE IMAGENS COM PERDAS

================================================================================

  • O formato JPEG permite compressão da imagem ao salvá-la num arquivo com o comando imwrite().

  • A compressão afeta a qualidade da imagem, sendo controlada pelo parâmetro IMWRITE_JPEG_QUALITY entre 0-100, sendo que quanto maior, melhor a qualidade. O default é 95.

In [14]:
bgr = cv.imread('./arquivos_notebook/lena.bmp')  # formato BGR

# salva com menor qualidade, fatores 25 e 5
cv.imwrite('lena25.jpg', bgr, [cv.IMWRITE_JPEG_QUALITY, 25])
cv.imwrite('lena05.jpg', bgr, [cv.IMWRITE_JPEG_QUALITY, 5])

# leitura para visualização e conversão para acertar a cor
rgb = cv.cvtColor(bgr, cv.COLOR_BGR2RGB)
bgr25 = cv.imread('lena25.jpg'); rgb25 = cv.cvtColor(bgr25, cv.COLOR_BGR2RGB)
bgr05 = cv.imread('lena05.jpg'); rgb05 = cv.cvtColor(bgr05, cv.COLOR_BGR2RGB)

plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(rgb); plt.title('RGB Original')
plt.subplot(132); plt.imshow(rgb25); plt.title('JPEG fator 25')
plt.subplot(133); plt.imshow(rgb05); plt.title('JPEG fator 05')
Out[14]:
Text(0.5, 1.0, 'JPEG fator 05')

COM AS FOTOS DO GRUPO¶

  1. Repita o procedimento para cada uma das fotos dos integrantes do grupo e para a foto-montagem do grupo todo
  2. Leia o tamanho dos arquivos (em bytes) e faça uma tabela comparando os tamanhos originais e os comprimidos e calcule a porcentagem de compressão de cada arquivo destes tamanhos na tabela construída
In [15]:
cv.imwrite('adinan25.jpg', adinan_bgr, [cv.IMWRITE_JPEG_QUALITY, 25])
cv.imwrite('adinan05.jpg', adinan_bgr, [cv.IMWRITE_JPEG_QUALITY, 5])

adinan_rgb = cv.cvtColor(adinan_bgr, cv.COLOR_BGR2RGB)
adinan25 = cv.imread('adinan25.jpg'); adinan25 = cv.cvtColor(adinan25, cv.COLOR_BGR2RGB)
adinan05 = cv.imread('adinan05.jpg'); adinan05 = cv.cvtColor(adinan05, cv.COLOR_BGR2RGB)

plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(adinan_rgb); plt.title('RGB Original')
plt.subplot(132); plt.imshow(adinan25); plt.title('JPEG fator 25')
plt.subplot(133); plt.imshow(adinan05); plt.title('JPEG fator 05')
Out[15]:
Text(0.5, 1.0, 'JPEG fator 05')
In [16]:
cv.imwrite('joao25.jpg', joao_bgr, [cv.IMWRITE_JPEG_QUALITY, 25])
cv.imwrite('joao05.jpg', joao_bgr, [cv.IMWRITE_JPEG_QUALITY, 5])

joao_rgb = cv.cvtColor(joao_bgr, cv.COLOR_BGR2RGB)
joao25 = cv.imread('joao25.jpg'); joao25 = cv.cvtColor(joao25, cv.COLOR_BGR2RGB)
joao05 = cv.imread('joao05.jpg'); joao05 = cv.cvtColor(joao05, cv.COLOR_BGR2RGB)

plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(joao_rgb); plt.title('RGB Original')
plt.subplot(132); plt.imshow(joao25); plt.title('JPEG fator 25')
plt.subplot(133); plt.imshow(joao05); plt.title('JPEG fator 05')
Out[16]:
Text(0.5, 1.0, 'JPEG fator 05')
In [17]:
cv.imwrite('marcelo25.jpg', marcelo_bgr, [cv.IMWRITE_JPEG_QUALITY, 25])
cv.imwrite('marcelo05.jpg', marcelo_bgr, [cv.IMWRITE_JPEG_QUALITY, 5])
marcelo_rgb = cv.cvtColor(marcelo_bgr, cv.COLOR_BGR2RGB)

marcelo25 = cv.imread('marcelo25.jpg'); marcelo25 = cv.cvtColor(marcelo25, cv.COLOR_BGR2RGB)
marcelo05 = cv.imread('marcelo05.jpg'); marcelo05 = cv.cvtColor(marcelo05, cv.COLOR_BGR2RGB)

plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(marcelo_rgb); plt.title('RGB Original')
plt.subplot(132); plt.imshow(marcelo25); plt.title('JPEG fator 25')
plt.subplot(133); plt.imshow(marcelo05); plt.title('JPEG fator 05')
Out[17]:
Text(0.5, 1.0, 'JPEG fator 05')
In [18]:
cv.imwrite('walter25.jpg', walter_bgr, [cv.IMWRITE_JPEG_QUALITY, 25])
cv.imwrite('walter05.jpg', walter_bgr, [cv.IMWRITE_JPEG_QUALITY, 5])

walter_rgb = cv.cvtColor(walter_bgr, cv.COLOR_BGR2RGB)

walter25 = cv.imread('walter25.jpg'); walter25 = cv.cvtColor(walter25, cv.COLOR_BGR2RGB)
walter05 = cv.imread('walter05.jpg'); walter05 = cv.cvtColor(walter05, cv.COLOR_BGR2RGB)

plt.figure(figsize=[15,6])
plt.subplot(131); plt.imshow(walter_rgb); plt.title('RGB Original')
plt.subplot(132); plt.imshow(walter25); plt.title('JPEG fator 25')
plt.subplot(133); plt.imshow(walter05); plt.title('JPEG fator 05')
Out[18]:
Text(0.5, 1.0, 'JPEG fator 05')

Comparação de tamanho¶

In [19]:
from tabulate import tabulate
import os
size_adinan_original = os.path.getsize('./fotos_grupo/adinan_home.jpg')
size_adinan_25 = os.path.getsize('./adinan25.jpg')
size_adinan_05 = os.path.getsize('./adinan05.jpg')

size_joao_original = os.path.getsize('./fotos_grupo/joao_home.jpg')
size_joao_25 = os.path.getsize('./joao25.jpg')
size_joao_05 = os.path.getsize('./joao05.jpg')

size_marcelo_original = os.path.getsize('./fotos_grupo/marcelo_home.jpg')
size_marcelo_25 = os.path.getsize('./joao25.jpg')
size_marcelo_05 = os.path.getsize('./joao05.jpg')

size_walter_original = os.path.getsize('./fotos_grupo/walter_home.jpg')
size_walter_25 = os.path.getsize('./walter25.jpg')
size_walter_05 = os.path.getsize('./walter05.jpg')
data = [
    ['Adinan', 'RGB Original', size_adinan_original, 100 -(size_adinan_original/size_adinan_original)*100],
    ['Adinan', 'JPEG fator 25', size_adinan_25, 100 -(size_adinan_25/size_adinan_original)*100],
    ['Adinan', 'JPEG fator 05', size_adinan_05, 100 -(size_adinan_05/size_adinan_original)*100],
    ['João', 'RGB Original', size_joao_original, 100 -(size_joao_original/size_joao_original)*100],
    ['João', 'JPEG fator 25', size_joao_25, 100 -(size_joao_25/size_joao_original)*100],
    ['João', 'JPEG fator 05', size_joao_05, 100 -(size_joao_05/size_joao_original)*100],
    ['Marcelo', 'RGB Original', size_marcelo_original, 100 -(size_marcelo_original/size_marcelo_original)*100],
    ['Marcelo', 'JPEG fator 25', size_marcelo_25, 100 -(size_marcelo_25/size_marcelo_original)*100],
    ['Marcelo', 'JPEG fator 05', size_marcelo_05, 100 -(size_marcelo_05/size_marcelo_original)*100],   
    ['Walter', 'RGB Original', size_walter_original, 100 -(size_walter_original/size_walter_original)*100],
    ['Walter', 'JPEG fator 25', size_walter_25, 100 -(size_walter_25/size_walter_original)*100],
    ['Walter', 'JPEG fator 05', size_walter_05, 100 -(size_walter_05/size_walter_original)*100],
]
print (tabulate(data, headers=["Imagem", "Compressão", "Tamanho (bytes)", "% Compressão"]))
Imagem    Compressão       Tamanho (bytes)    % Compressão
--------  -------------  -----------------  --------------
Adinan    RGB Original              198515          0
Adinan    JPEG fator 25              41598         79.0454
Adinan    JPEG fator 05              21753         89.0421
João      RGB Original              394827          0
João      JPEG fator 25              43207         89.0567
João      JPEG fator 05              21970         94.4355
Marcelo   RGB Original              202133          0
Marcelo   JPEG fator 25              43207         78.6245
Marcelo   JPEG fator 05              21970         89.1309
Walter    RGB Original              326437          0
Walter    JPEG fator 25              40436         87.6129
Walter    JPEG fator 05              22082         93.2354

TRANSFORMADA DISCRETA COSSENO¶


Nesta parte calcule a DCT em bloco de 8x8 da imagem, referente à bola

In [20]:
img = cv.imread('./arquivos_notebook/messi.jpg')
alt, larg, cam = img.shape

ycbcr = cv.cvtColor(img, cv.COLOR_BGR2YCrCb)
y, cr, cb = cv.split(ycrcb)

bola = y[280:340, 330:390]
h, w = bola.shape

cx = round(w/2)
cy = round(h/2)

# Escolhendo um pedaço da imagem "BOLA"
bloco8x8 = bola[cx-4:cx+4, cy-4:cy+4]
print("(1)"); print("Matriz 8x8: componente Y original")
print(bloco8x8)

bloco8x8f = np.float32(bloco8x8)/255.0  # conversão para float
dct8x8f = cv.dct(bloco8x8f)   # calcula a DCT
dct8x8 = np.int64( (dct8x8f*255.0)) # coversão para inteiro

print("(2)"); print("Imagem Y 8x8 (formato ponto flutuante)")
print( np.around(bloco8x8f, decimals = 2) )

print("(3)"); print("DCT de Y (ponto flutuante)")
print( np.around(dct8x8f, decimals = 2) )

print("(4)"); print("DCT de Y (formato inteiro)")
print(dct8x8)
(1)
Matriz 8x8: componente Y original
[[216 224 158  56  69  67  60 111]
 [212 218 101  51 137 181 195 190]
 [207 220  80  65 194 244 247 235]
 [208 215 100 126 105 197 221 195]
 [210 215 154 159  93 112 152 176]
 [198 213 213 106  96  92  83  61]
 [192 209 215 170  32  21  64  70]
 [225 195 209 220 211 117  72 152]]
(2)
Imagem Y 8x8 (formato ponto flutuante)
[[0.85 0.88 0.62 0.22 0.27 0.26 0.24 0.44]
 [0.83 0.85 0.4  0.2  0.54 0.71 0.76 0.75]
 [0.81 0.86 0.31 0.25 0.76 0.96 0.97 0.92]
 [0.82 0.84 0.39 0.49 0.41 0.77 0.87 0.76]
 [0.82 0.84 0.6  0.62 0.36 0.44 0.6  0.69]
 [0.78 0.84 0.84 0.42 0.38 0.36 0.33 0.24]
 [0.75 0.82 0.84 0.67 0.13 0.08 0.25 0.27]
 [0.88 0.76 0.82 0.86 0.83 0.46 0.28 0.6 ]]
(3)
DCT de Y (ponto flutuante)
[[ 4.81  0.76  0.76  0.05 -0.15 -0.2  -0.09 -0.07]
 [ 0.06 -0.56  0.52  0.47 -0.21 -0.24 -0.09  0.  ]
 [-0.26  0.47 -0.2  -0.19  0.18 -0.12  0.14  0.14]
 [-0.63  0.67  0.   -0.36 -0.14  0.11  0.1   0.06]
 [ 0.09  0.07 -0.05 -0.12  0.22  0.03  0.02 -0.1 ]
 [-0.27  0.19  0.06 -0.13 -0.12  0.12 -0.01 -0.08]
 [ 0.12 -0.03 -0.13  0.17  0.02 -0.18  0.08  0.13]
 [ 0.   -0.    0.05 -0.12  0.09  0.01 -0.04 -0.02]]
(4)
DCT de Y (formato inteiro)
[[1226  193  194   12  -39  -50  -23  -17]
 [  15 -141  132  119  -54  -62  -22    1]
 [ -65  120  -50  -49   46  -29   35   36]
 [-159  171    0  -92  -36   27   24   15]
 [  23   16  -13  -31   55    8    6  -25]
 [ -68   47   14  -32  -29   30   -3  -19]
 [  29   -6  -33   42    3  -47   19   33]
 [   0   -1   13  -31   21    1  -10   -5]]

ZERANDO manualmente da diagonal da DCT as componentes AC

In [21]:
dct8x8fz = dct8x8f.copy()
dct8x8fz[0,7] = 0
dct8x8fz[1,6:8] = 0
dct8x8fz[2,5:8] = 0
dct8x8fz[3,4:8] = 0
dct8x8fz[4,3:8] = 0
dct8x8fz[5,2:8] = 0
dct8x8fz[6,1:8] = 0
dct8x8fz[7,0:8] = 0
print( np.around(dct8x8fz, decimals = 2))
[[ 4.81  0.76  0.76  0.05 -0.15 -0.2  -0.09  0.  ]
 [ 0.06 -0.56  0.52  0.47 -0.21 -0.24  0.    0.  ]
 [-0.26  0.47 -0.2  -0.19  0.18  0.    0.    0.  ]
 [-0.63  0.67  0.   -0.36  0.    0.    0.    0.  ]
 [ 0.09  0.07 -0.05  0.    0.    0.    0.    0.  ]
 [-0.27  0.19  0.    0.    0.    0.    0.    0.  ]
 [ 0.12  0.    0.    0.    0.    0.    0.    0.  ]
 [ 0.    0.    0.    0.    0.    0.    0.    0.  ]]

Bloco Original e Reconstruído com Zeros das componentes AC da diagonal para baixo zerados

In [23]:
bloco8x8recz = cv.idct(dct8x8fz)

plt.subplot(121); plt.imshow(bloco8x8,'gray'); plt.title('Bloco Original')
plt.subplot(122); plt.imshow(bloco8x8recz,'gray'); plt.title('Bloco Reconstruído com Zeros')
Out[23]:
Text(0.5, 1.0, 'Bloco Reconstruído com Zeros')

Escolha outro bloco de 8x8 da imagem e:¶

  1. refaça este procedimento zerando mais DUAS DIAGONAIS ACIMA DA PRINCIPAL além destas
  2. Compare e comente as imagens do bloco original e reconstruída
In [40]:
# Escolhendo um pedaço da imagem "BOLA"
novo_bloco8x8 = y[100:108, 200:208]
print("(1)"); print("Matriz 8x8: componente Y original")
print(novo_bloco8x8)

novo_bloco8x8f = np.float32(novo_bloco8x8)/255.0  # conversão para float
novadct8x8f = cv.dct(novo_bloco8x8f)   # calcula a DCT
novadct8x8 = np.int64( (novadct8x8f*255.0)) # coversão para inteiro

print("(2)"); print("Imagem Y 8x8 (formato ponto flutuante)")
print( np.around(novo_bloco8x8f, decimals = 2) )
(1)
Matriz 8x8: componente Y original
[[70 61 53 49 40 34 41 87]
 [67 57 53 43 34 37 39 40]
 [65 57 51 46 42 25 31 37]
 [60 53 49 42 32 30 21 27]
 [54 55 42 40 35 24 25 23]
 [52 53 47 39 32 25 23 22]
 [55 43 44 41 30 25 23 21]
 [48 43 42 36 29 28 26 24]]
(2)
Imagem Y 8x8 (formato ponto flutuante)
[[0.27 0.24 0.21 0.19 0.16 0.13 0.16 0.34]
 [0.26 0.22 0.21 0.17 0.13 0.15 0.15 0.16]
 [0.25 0.22 0.2  0.18 0.16 0.1  0.12 0.15]
 [0.24 0.21 0.19 0.16 0.13 0.12 0.08 0.11]
 [0.21 0.22 0.16 0.16 0.14 0.09 0.1  0.09]
 [0.2  0.21 0.18 0.15 0.13 0.1  0.09 0.09]
 [0.22 0.17 0.17 0.16 0.12 0.1  0.09 0.08]
 [0.19 0.17 0.16 0.14 0.11 0.11 0.1  0.09]]
In [41]:
print("(3)"); print("DCT de Y (ponto flutuante)")
print( np.around(novadct8x8f, decimals = 2) )

print("(4)"); print("DCT de Y (formato inteiro)")
print(novadct8x8)
(3)
DCT de Y (ponto flutuante)
[[ 1.29  0.31  0.1  -0.04  0.05 -0.    0.01 -0.  ]
 [ 0.18 -0.04  0.09 -0.04  0.04 -0.02  0.01 -0.  ]
 [ 0.06 -0.08  0.06 -0.03  0.02  0.    0.02 -0.  ]
 [ 0.03 -0.03  0.03 -0.03  0.02 -0.02 -0.   -0.01]
 [ 0.01 -0.03  0.03 -0.02  0.02 -0.02  0.01 -0.02]
 [ 0.02 -0.01  0.01 -0.02  0.04 -0.01  0.02 -0.01]
 [ 0.02 -0.01  0.01 -0.03  0.02 -0.02 -0.01  0.01]
 [ 0.01 -0.01  0.01 -0.01  0.03 -0.   -0.02  0.01]]
(4)
DCT de Y (formato inteiro)
[[327  78  26 -11  12   0   2   0]
 [ 47 -10  22 -10  11  -6   2  -1]
 [ 16 -19  14  -7   5   0   6  -1]
 [  8  -6   8  -7   3  -5   0  -2]
 [  2  -8   6  -4   4  -6   1  -4]
 [  4  -1   3  -5   9  -1   5  -1]
 [  5  -3   2  -6   4  -6  -2   1]
 [  3  -2   1  -1   7  -1  -5   2]]
In [42]:
y[0,1]
Out[42]:
46
In [43]:
novadct8x8fz = novadct8x8f.copy()
novadct8x8fz[0,5:8] = 0
novadct8x8fz[1,4:8] = 0
novadct8x8fz[2,3:8] = 0
novadct8x8fz[3,2:8] = 0
novadct8x8fz[4,1:8] = 0
novadct8x8fz[5,0:8] = 0
novadct8x8fz[6,0:8] = 0
novadct8x8fz[7,0:8] = 0
print( np.around(novadct8x8fz, decimals = 2))
[[ 1.29  0.31  0.1  -0.04  0.05  0.    0.    0.  ]
 [ 0.18 -0.04  0.09 -0.04  0.    0.    0.    0.  ]
 [ 0.06 -0.08  0.06  0.    0.    0.    0.    0.  ]
 [ 0.03 -0.03  0.    0.    0.    0.    0.    0.  ]
 [ 0.01  0.    0.    0.    0.    0.    0.    0.  ]
 [ 0.    0.    0.    0.    0.    0.    0.    0.  ]
 [ 0.    0.    0.    0.    0.    0.    0.    0.  ]
 [ 0.    0.    0.    0.    0.    0.    0.    0.  ]]
In [44]:
novobloco8x8recz = cv.idct(novadct8x8fz)

plt.subplot(121); plt.imshow(novo_bloco8x8,'gray'); plt.title('Bloco Original')
plt.subplot(122); plt.imshow(novobloco8x8recz,'gray'); plt.title('Bloco Reconstruído com Zeros')
Out[44]:
Text(0.5, 1.0, 'Bloco Reconstruído com Zeros')

Analisando o processamento DCT efetuado no outro bloco de 8x8 pixels da imagem, nota-se que houve uma suavização das intensidades de luminosidade em pixels vizinhos. Isso ocorre devido a perda das componentes de altas frequências da DCT, que são responsáveis pela formação de imagens com alto nível de contraste entre tais pixels.

Tal comportamento é evidente no último pixel da primeira linha, onde no bloco original apenas ele é de tonalidade clara, enquanto que no bloco reconstruído com mascaramento de coeficientes de alta frequência, toda a vizinhança desse pixel foi afetada pela sua luminosidade, gerando um efeito de desfoque.